<script setup>
// 游戏元素引用
const tetrisCanvas = ref(null);
let ctx = null;
let gameInterval = null;

// 游戏状态
const board = ref([]);
const currentPiece = ref(null);
const nextPiece = ref(null);
const score = ref(0);
const level = ref(1);
const lines = ref(0);
const isPaused = ref(false);
const isGameOver = ref(false);
const isGameStarted = ref(false);
const showStartScreen = ref(true);

// 游戏配置
const gridSize = 20;
const rows = 20;
const cols = 10;
const baseGameSpeed = 1000; // 基础速度（毫秒）
const gameSpeed = ref(baseGameSpeed);

// 方块形状定义
const shapes = [
  // I 型
  [
    [0, 0, 0, 0],
    [1, 1, 1, 1],
    [0, 0, 0, 0],
    [0, 0, 0, 0]
  ],
  // J 型
  [
    [2, 0, 0],
    [2, 2, 2],
    [0, 0, 0]
  ],
  // L 型
  [
    [0, 0, 3],
    [3, 3, 3],
    [0, 0, 0]
  ],
  // O 型
  [
    [4, 4],
    [4, 4]
  ],
  // S 型
  [
    [0, 5, 5],
    [5, 5, 0],
    [0, 0, 0]
  ],
  // T 型
  [
    [0, 6, 0],
    [6, 6, 6],
    [0, 0, 0]
  ],
  // Z 型
  [
    [7, 7, 0],
    [0, 7, 7],
    [0, 0, 0]
  ]
];

// 方块颜色
const colors = [
  null, // 空
  '#00FFFF', // I 型：青色
  '#0000FF', // J 型：蓝色
  '#FFA500', // L 型：橙色
  '#FFFF00', // O 型：黄色
  '#00FF00', // S 型：绿色
  '#800080', // T 型：紫色
  '#FF0000'  // Z 型：红色
];

// 添加预览画布引用
const nextPieceCanvas = ref(null);
let nextPieceCtx = null;

// 初始化游戏板
function initBoard() {
  board.value = Array.from({ length: rows }, () => Array(cols).fill(0));
}

// 随机生成一个新方块
function generatePiece() {
  const type = Math.floor(Math.random() * shapes.length);
  const shape = shapes[type];
  return {
    shape,
    type: type + 1, // 从1开始
    x: Math.floor(cols / 2) - Math.floor(shape[0].length / 2),
    y: 0
  };
}

// 检查碰撞
function checkCollision(piece, offsetX = 0, offsetY = 0) {
  for (let y = 0; y < piece.shape.length; y++) {
    for (let x = 0; x < piece.shape[y].length; x++) {
      if (piece.shape[y][x] !== 0) {
        const newX = piece.x + x + offsetX;
        const newY = piece.y + y + offsetY;

        // 检查边界
        if (
          newX < 0 ||
          newX >= cols ||
          newY >= rows ||
          (newY >= 0 && board.value[newY][newX] !== 0)
        ) {
          return true;
        }
      }
    }
  }
  return false;
}

// 旋转方块
function rotatePiece(piece) {
  // 创建旋转后的形状矩阵
  const rows = piece.shape.length;
  const cols = piece.shape[0].length;
  const rotatedShape = Array.from({ length: cols }, () => Array(rows).fill(0));

  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      rotatedShape[i][j] = piece.shape[rows - 1 - j][i];
    }
  }

  const rotatedPiece = {
    ...piece,
    shape: rotatedShape
  };

  // 检查旋转后的位置是否有效
  if (!checkCollision(rotatedPiece)) {
    return rotatedPiece;
  }

  // 尝试墙踢
  const wallKicks = [[1, 0], [-1, 0], [0, -1], [1, -1], [-1, -1]];
  for (const [kickX, kickY] of wallKicks) {
    if (!checkCollision(rotatedPiece, kickX, kickY)) {
      rotatedPiece.x += kickX;
      rotatedPiece.y += kickY;
      return rotatedPiece;
    }
  }

  // 无法旋转，返回原方块
  return piece;
}

// 锁定当前方块到游戏板
function lockPiece() {
  for (let y = 0; y < currentPiece.value.shape.length; y++) {
    for (let x = 0; x < currentPiece.value.shape[y].length; x++) {
      if (currentPiece.value.shape[y][x] !== 0) {
        const boardY = currentPiece.value.y + y;
        const boardX = currentPiece.value.x + x;
        if (boardY >= 0) {
          board.value[boardY][boardX] = currentPiece.value.type;
        }
      }
    }
  }

  // 检查并清除完整的行
  clearLines();

  // 更新下一个方块
  currentPiece.value = nextPiece.value;
  nextPiece.value = generatePiece();
  drawNextPiece(); // 更新下一个方块预览

  // 检查游戏是否结束
  if (checkCollision(currentPiece.value)) {
    gameOver();
  }
}

// 清除完整的行
function clearLines() {
  let linesCleared = 0;
  for (let row = rows - 1; row >= 0; row--) {
    if (board.value[row].every(cell => cell !== 0)) {
      // 移除完整的行
      board.value.splice(row, 1);
      // 在顶部添加一行空行
      board.value.unshift(Array(cols).fill(0));
      // 增加计数器并重新检查当前行
      linesCleared++;
      row++;
    }
  }

  if (linesCleared > 0) {
    // 更新分数和等级
    updateScore(linesCleared);
    lines.value += linesCleared;
    checkLevel();
  }
}

// 更新分数（经典俄罗斯方块计分规则）
function updateScore(linesCleared) {
  const scoreMap = { 1: 100, 2: 300, 3: 500, 4: 800 };
  score.value += (scoreMap[linesCleared] || 0) * level.value;
}

// 检查并更新等级
function checkLevel() {
  const newLevel = Math.floor(lines.value / 10) + 1;
  if (newLevel > level.value) {
    level.value = newLevel;
    // 增加游戏速度
    gameSpeed.value = Math.max(100, baseGameSpeed - (level.value - 1) * 80);
    // 重新设置游戏循环以应用新速度
    if (gameInterval) {
      clearInterval(gameInterval);
      gameInterval = setInterval(updateGame, gameSpeed.value);
    }
  }
}

// 绘制游戏板
function drawBoard() {
  if (!ctx) return;

  // 清空画布
  ctx.clearRect(0, 0, cols * gridSize, rows * gridSize);

  // 绘制背景网格
  ctx.strokeStyle = '#e0e0e0';
  ctx.lineWidth = 0.5;
  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      ctx.strokeRect(col * gridSize, row * gridSize, gridSize, gridSize);
    }
  }

  // 绘制已锁定的方块
  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      if (board.value[row][col] !== 0) {
        drawCell(col, row, board.value[row][col]);
      }
    }
  }

  // 绘制当前方块
  if (currentPiece.value) {
    for (let y = 0; y < currentPiece.value.shape.length; y++) {
      for (let x = 0; x < currentPiece.value.shape[y].length; x++) {
        if (currentPiece.value.shape[y][x] !== 0) {
          const boardX = currentPiece.value.x + x;
          const boardY = currentPiece.value.y + y;
          if (boardY >= 0) {
            drawCell(boardX, boardY, currentPiece.value.shape[y][x]);
          }
        }
      }
    }
  }
}

// 绘制单个方块
function drawCell(x, y, type) {
  if (!ctx) return;

  const color = colors[type];

  // 绘制方块主体
  ctx.fillStyle = color;
  ctx.fillRect(x * gridSize, y * gridSize, gridSize - 1, gridSize - 1);

  // 绘制高光
  ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
  ctx.fillRect(x * gridSize, y * gridSize, gridSize - 1, 4);
  ctx.fillRect(x * gridSize, y * gridSize, 4, gridSize - 1);

  // 绘制阴影
  ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
  ctx.fillRect(x * gridSize + (gridSize - 1 - 4), y * gridSize, 4, gridSize - 1);
  ctx.fillRect(x * gridSize, y * gridSize + (gridSize - 1 - 4), gridSize - 1, 4);
}

// 更新游戏状态
function updateGame() {
  if (!isPaused.value && !isGameOver.value) {
    // 尝试向下移动方块
    if (!checkCollision(currentPiece.value, 0, 1)) {
      currentPiece.value.y++;
    } else {
      // 无法移动，锁定方块
      lockPiece();
    }

    // 重绘游戏
    drawBoard();
  }
}

// 修改drawNextPiece函数，修正绘制逻辑
function drawNextPiece() {
  if (!nextPieceCtx || !nextPiece.value) return;

  // 清空画布
  nextPieceCtx.clearRect(0, 0, 100, 100);

  // 绘制背景网格
  nextPieceCtx.strokeStyle = '#e0e0e0';
  nextPieceCtx.lineWidth = 0.5;
  for (let row = 0; row < 5; row++) {
    for (let col = 0; col < 5; col++) {
      nextPieceCtx.strokeRect(col * gridSize, row * gridSize, gridSize, gridSize);
    }
  }

  // 计算方块居中显示的偏移量（优化居中算法）
  const pieceWidth = nextPiece.value.shape[0].length;
  const pieceHeight = nextPiece.value.shape.length;
  const offsetX = Math.floor((5 - pieceWidth) / 2) * gridSize;
  const offsetY = Math.floor((5 - pieceHeight) / 2) * gridSize;

  // 绘制预览方块
  for (let y = 0; y < pieceHeight; y++) {
    for (let x = 0; x < pieceWidth; x++) {
      if (nextPiece.value.shape[y][x] !== 0) {
        const color = colors[nextPiece.value.shape[y][x]];

        // 绘制方块主体
        nextPieceCtx.fillStyle = color;
        nextPieceCtx.fillRect(
          offsetX + x * gridSize,
          offsetY + y * gridSize,
          gridSize - 1,
          gridSize - 1
        );

        // 绘制高光
        nextPieceCtx.fillStyle = 'rgba(255, 255, 255, 0.3)';
        nextPieceCtx.fillRect(offsetX + x * gridSize, offsetY + y * gridSize, gridSize - 1, 4);
        nextPieceCtx.fillRect(offsetX + x * gridSize, offsetY + y * gridSize, 4, gridSize - 1);

        // 绘制阴影
        nextPieceCtx.fillStyle = 'rgba(0, 0, 0, 0.1)';
        nextPieceCtx.fillRect(offsetX + x * gridSize + (gridSize - 1 - 4), offsetY + y * gridSize, 4, gridSize - 1);
        nextPieceCtx.fillRect(offsetX + x * gridSize, offsetY + y * gridSize + (gridSize - 1 - 4), gridSize - 1, 4);
      }
    }
  }
}

// 游戏控制函数
function startGame() {
  // 初始化游戏状态
  initBoard();
  currentPiece.value = generatePiece();
  nextPiece.value = generatePiece();
  score.value = 0;
  level.value = 1;
  lines.value = 0;
  gameSpeed.value = baseGameSpeed;
  isPaused.value = false;
  isGameOver.value = false;
  isGameStarted.value = true;
  showStartScreen.value = false;

  // 设置游戏循环
  if (gameInterval) {
    clearInterval(gameInterval);
  }
  gameInterval = setInterval(updateGame, gameSpeed.value);

  // 初始绘制
  drawBoard();
  drawNextPiece(); // 绘制下一个方块预览
}

function pauseGame() {
  isPaused.value = true;
}

function resumeGame() {
  isPaused.value = false;
}

function resetGame() {
  // 清除游戏循环
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }

  // 开始新游戏
  startGame();
}

function exitGame() {
  // 清除游戏循环
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }

  // 重置游戏进度数据
  score.value = 0;
  level.value = 1;
  lines.value = 0;
  gameSpeed.value = baseGameSpeed;

  // 重置游戏板和方块状态
  initBoard(); // 重新初始化游戏板
  currentPiece.value = null; // 清除当前方块
  nextPiece.value = null; // 清除下一个方块

  // 重置游戏状态
  isGameStarted.value = false;
  isGameOver.value = false;
  isPaused.value = false;
  showStartScreen.value = true;

  // 清空画布显示初始状态
  if (ctx) {
    ctx.clearRect(0, 0, tetrisCanvas.value.width, tetrisCanvas.value.height);
    drawBoard(); // 绘制空游戏板
  }

  // 清空预览画布
  if (nextPieceCtx) {
    nextPieceCtx.clearRect(0, 0, nextPieceCanvas.value.width, nextPieceCanvas.value.height);
  }
}


function gameOver() {
  isGameOver.value = true;
  isGameStarted.value = false;

  // 清除游戏循环
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }
}

// 键盘事件处理
function handleKeydown(event) {
  // 阻止方向键和空格键的默认行为（防止页面滚动）
  if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(event.key)) {
    event.preventDefault();
  }
  // 对空格键特殊处理，其他键需要游戏进行中才能响应
  if (event.key !== ' ' && (!isGameStarted.value || isGameOver.value || isPaused.value)) {
    return;
  }

  switch (event.key) {
    case 'ArrowLeft':
      // 左移
      if (!checkCollision(currentPiece.value, -1, 0)) {
        currentPiece.value.x--;
        drawBoard();
      }
      break;
    case 'ArrowRight':
      // 右移
      if (!checkCollision(currentPiece.value, 1, 0)) {
        currentPiece.value.x++;
        drawBoard();
      }
      break;
    case 'ArrowDown':
      // 下移
      if (!checkCollision(currentPiece.value, 0, 1)) {
        currentPiece.value.y++;
        drawBoard();
      }
      break;
    case 'ArrowUp':
      // 旋转
      currentPiece.value = rotatePiece(currentPiece.value);
      drawBoard();
      break;
    case ' ': // 空格键 - 修改为暂停/开始游戏
      if (isGameOver.value) {
        // 游戏结束时不执行任何操作
        return;
      } else if (!isGameStarted.value) {
        // 游戏未开始时，开始游戏
        startGame();
      } else if (isPaused.value) {
        // 游戏暂停时，继续游戏
        resumeGame();
      } else {
        // 游戏进行中，暂停游戏
        pauseGame();
      }
      break;
  }
}

// 生命周期钩子
onMounted(() => {
  // 获取画布上下文
  if (tetrisCanvas.value) {
    ctx = tetrisCanvas.value.getContext('2d');
  }

  // 获取预览画布上下文
  if (nextPieceCanvas.value) {
    nextPieceCtx = nextPieceCanvas.value.getContext('2d');
  }
  // 添加键盘事件监听
  window.addEventListener('keydown', handleKeydown);
});

onUnmounted(() => {
  // 清除游戏循环
  if (gameInterval) {
    clearInterval(gameInterval);
  }

  // 移除键盘事件监听
  window.removeEventListener('keydown', handleKeydown);
});
</script>
<template>
  <div class="game-container">
    <!-- 游戏页面 -->
    <div class="game-page">
      <!-- 游戏画布 -->
      <div class="page-container">
        <canvas
          ref="tetrisCanvas"
          width="200"
          height="400"
        ></canvas>
        <!-- 下一个方块预览区域 -->
        <div class="next-piece-section">
          <h3>下一个</h3>
          <div class="next-piece-container">
            <canvas
              ref="nextPieceCanvas"
              width="100"
              height="100"
            ></canvas>
          </div>
        </div>

      </div>

      <!-- 分数和控制区域 -->
      <div class="game-controls">
        <!-- 分数统计 -->
        <div class="status-info">
          <div class="score-section">
            <h3>分数</h3>
            <p class="score-value">{{ score }}</p>
          </div>
          <div class="level-section">
            <h3>等级</h3>
            <p class="level-value">{{ level }}</p>
          </div>
          <div class="lines-section">
            <h3>行数</h3>
            <p class="lines-value">{{ lines }}</p>
          </div>
        </div>

        <!-- 控制按钮 -->
        <div class="button-group">
          <el-button
            @click="startGame"
            v-if="!isGameStarted"
            type="primary"
            size="large"
          >
            开始游戏
          </el-button>
          <el-button
            @click="pauseGame"
            v-else-if="!isPaused"
            size="large"
          >
            暂停游戏
          </el-button>
          <el-button
            @click="resumeGame"
            v-else
            type="primary"
            size="large"
          >
            继续游戏
          </el-button>
          <el-button
            @click="resetGame"
            v-if="isGameStarted"
            size="large"
          >
            重新开始
          </el-button>
        </div>
      </div>

      <!-- 开始界面 -->
      <div
        v-if="showStartScreen"
        class="start-screen"
      >
        <h1>俄罗斯方块</h1>
        <p>使用方向键控制方块移动和旋转<br>空格键暂停/开始游戏<br>游戏将根据消除行数提升等级和速度</p>
        <p style="color: #f44336; margin-bottom: 30px;">仅适用于电脑端操控</p>
        <el-button
          @click="startGame"
          type="primary"
          size="large"
        >开始游戏</el-button>
      </div>

      <!-- 游戏结束界面 -->
      <div
        v-if="isGameOver"
        class="game-over-screen"
      >
        <h1>游戏结束</h1>
        <div class="final-stats">
          <div class="final-score">
            <div class="final-stats-label">最终分数</div>
            <div class="final-value">{{ score }}</div>
          </div>
          <div class="final-level">
            <div class="final-stats-label">最终等级</div>
            <div class="final-value">{{ level }}</div>
          </div>
          <div class="final-lines">
            <div class="final-stats-label">消除行数</div>
            <div class="final-value">{{ lines }}</div>
          </div>
        </div>
        <div class="btn-group">
          <el-button
            @click="resetGame"
            type="primary"
            size="large"
          >重新开始</el-button>
          <el-button
            @click="exitGame"
            type="danger"
            size="large"
          >退出游戏</el-button>
        </div>
      </div>

      <!-- 暂停界面 -->
      <div
        v-if="isPaused && !isGameOver"
        class="pause-screen"
      >
        <h1>游戏暂停</h1>
        <p style="margin-bottom: 20px; font-size: 18px;">按空格键继续游戏</p>
        <div class="btn-group">
          <el-button
            @click="resumeGame"
            type="primary"
            size="large"
          >继续游戏</el-button>
          <el-button
            @click="exitGame"
            type="danger"
            size="large"
          >退出游戏</el-button>
        </div>
      </div>
    </div>
  </div>
</template>



<style scoped>
/* 游戏容器 */
.game-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  background-color: var(--bg-color);
  color: var(--text-color);
  position: relative;
  overflow: hidden;
}

/* 游戏页面 */
.game-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 516px;
  gap: 15px;
  padding: 15px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(10px);
  border: 3px solid #333;
  position: relative;
}

/* 画布容器 */
.page-container {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f5f5;
  border-radius: 10px;
  padding: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 画布 */
.page-container canvas {
  border: 1px solid #333;
  border-radius: 5px;
  background-color: white;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
}

/* 下一个方块预览区域 */
.next-piece-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 15px 0;
  padding: 12px 15px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  width: 100%;
}

.next-piece-section h3 {
  margin: 0 0 10px 0;
  font-size: 16px;
  color: #888;
  font-weight: normal;
}

.next-piece-container {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f5f5;
  border-radius: 8px;
  padding: 5px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.next-piece-container canvas {
  border: 1px solid #ccc;
  border-radius: 4px;
  background-color: white;
}

/* 游戏控制区域 */
.game-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  width: 100%;
  max-width: 280px;
}

/* 状态信息 */
.status-info {
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 12px 15px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.score-section,
.level-section,
.lines-section {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.status-info h3 {
  margin: 0 0 5px 0;
  font-size: 13px;
  color: #888;
  font-weight: normal;
}

.score-value,
.level-value,
.lines-value {
  margin: 0;
  font-size: 20px;
  font-weight: bold;
  color: #333;
}

/* 按钮组 - 统一使用btn-group */
.btn-group {
  display: flex;
  gap: 15px;
  justify-content: center;
}

/* 界面公共样式 */
.start-screen,
.game-over-screen,
.pause-screen {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.85);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: white;
  z-index: 10;
  border-radius: 8px;
  backdrop-filter: blur(5px);
}

/* 全屏开始游戏界面样式 */
.start-screen h1 {
  font-size: 56px;
  margin-bottom: 20px;
  background: linear-gradient(45deg, #ffffff, #f0f0f0, #ffffff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  padding: 10px 30px;
  border-radius: 10px;
}

.start-screen p {
  font-size: 20px;
  margin-bottom: 30px;
  color: #e0e0e0;
  text-align: center;
}

/* 结算界面样式 */
.game-over-screen h1 {
  font-size: 56px;
  margin-bottom: 15px;
  text-shadow: 0 0 15px rgba(255, 0, 0, 0.7);
  background: linear-gradient(45deg, #f44336, #ff7961, #f44336);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  padding: 10px 30px;
  border-radius: 10px;
}

/* 暂停界面样式 */
.pause-screen h1 {
  font-size: 48px;
  margin-bottom: 30px;
  text-shadow: 0 0 15px rgba(255, 152, 0, 0.7);
  background: linear-gradient(45deg, #ff9800, #ffb74d, #ff9800);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* 美化结算信息 */
.final-stats {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  margin-bottom: 40px;
  padding: 20px 40px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 15px;
  border: 2px solid rgba(255, 255, 255, 0.2);
}

.final-score,
.final-level,
.final-lines {
  font-size: 28px;
  text-align: center;
}

.final-score {
  color: #ffd700;
  text-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
}

.final-level {
  color: #6c757d;
  text-shadow: 0 0 10px rgba(108, 117, 125, 0.5);
}

.final-lines {
  color: #4caf50;
  text-shadow: 0 0 10px rgba(76, 175, 80, 0.5);
}

.final-stats-label {
  font-size: 20px;
  color: #e0e0e0;
  margin-bottom: 5px;
}

.final-value {
  font-size: 32px;
  font-weight: bold;
  color: #ffffff;
}

/* 响应式设计 */
</style>